package com.huahan.auth.granter;

import com.huahan.auth.Utils.RedisHelper;
import com.huahan.auth.domain.UserInfo;
import com.huahan.auth.exception.BusinessException;
import com.huahan.auth.mapper.UserInfoMapper;
import com.huahan.auth.security.component.HuahanUserDetail;
import com.huahan.auth.service.UserService;
import com.mall.common.constant.CommonConstant;
import com.mall.common.constant.LoginTypeEnum;
import com.mall.common.constant.ResultCode;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.token.AbstractTokenGranter;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class SmsCodeTokenGranter extends AbstractTokenGranter {
    /***************************************************************
     *                                                             *
     * ***********************1-短信验证码授权************************
     *                                                             *
     * *************************************************************/
  private UserInfoMapper userInfoDao;

  public SmsCodeTokenGranter(AuthorizationServerTokenServices tokenServices,
                             ClientDetailsService clientDetailsService,
                             OAuth2RequestFactory requestFactory) {
    super(tokenServices, clientDetailsService, requestFactory,  LoginTypeEnum.SMS_CODE.getValue());
  }

  public void setAccountService(UserInfoMapper userInfoDao) {
    this.userInfoDao = userInfoDao;
  }
  @Override
  protected OAuth2Authentication getOAuth2Authentication(ClientDetails client,
      TokenRequest tokenRequest) {
      // TODO: 2022/5/11 根据项目实际使用情况调整 》》 已在com.huahan.system.service.impl.UserServiceImpl中实现
    Map<String, String> parameters = new LinkedHashMap<String, String>(tokenRequest.getRequestParameters());

    // 客户端提交的手机号码
    String phoneNumber = parameters.get(CommonConstant.DEFAULT_PARAMETER_NAME_PHONE);
    if (StringUtils.isBlank(phoneNumber)) {
      throw new BusinessException(ResultCode.PHONE_NUMBER_IS_EMPTY);
    }

    // 客户端提交的验证码
    String smsCode = parameters.get(CommonConstant.DEFAULT_PARAMETER_NAME_CODE_SMS);
    if (StringUtils.isBlank(smsCode)) {
      throw new BusinessException(ResultCode.SMS_CODE_IS_EMPTY);
    }

    // 客户端提交的手机号码 根据手机号码查询用户
    Map<String, Object> map = new HashMap<>();
    String loginType = parameters.get(CommonConstant.LOGIN_TYPE);
    map.put("phone_number", phoneNumber);
    if("2".equals(loginType)){
      map.put("is_app", "1");
    }
    List<UserInfo> list = userInfoDao.selectByMap(map);
      UserInfo userInfo = null;
    if(list.size()>0){
      userInfo = list.get(0);
    }
    // TODO: 2022/5/11 如果用户不存在，是否创建新用户？
    if(null == userInfo){
      throw new BusinessException(ResultCode.PHONE_NOT_EXITS);
    }
    if ("1".equals(userInfo.getStatus())){
        throw new BusinessException(ResultCode.ACCOUNT_DISABLED);
    }

    HuahanUserDetail userDetails = new HuahanUserDetail(userInfo, null);
    // 验证用户状态
    AbstractAuthenticationToken userAuth =
            new UsernamePasswordAuthenticationToken(userInfo, null, userDetails.getAuthorities());
    // 当然该参数传null也行
    userAuth.setDetails(parameters);
    OAuth2Request oAuth2Request = getRequestFactory().createOAuth2Request(client, tokenRequest);
    return new OAuth2Authentication(oAuth2Request, userAuth);
  }
}
